package com.mxpio.erp.oa.service.impl;

import com.google.common.collect.Lists;
import com.mxpio.erp.common.enums.BizExceptionEnums;
import com.mxpio.erp.common.enums.OaEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.handler.WorkerOrderStatusManager;
import com.mxpio.erp.common.model.request.BpmnSubmitRequest;
import com.mxpio.erp.common.oa.entity.OaCarApply;
import com.mxpio.erp.common.oa.service.OaCarApplyService;
import com.mxpio.erp.common.util.AssertUtil;
import com.mxpio.erp.common.util.CloneUtil;
import com.mxpio.erp.common.util.JacksonMapUtils;
import com.mxpioframework.camunda.service.BpmnFlowService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.PojoDictParseService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

;

@Service
public class OaCarApplyServiceImpl extends BaseServiceImpl<OaCarApply> implements OaCarApplyService {

        @Resource
        private BpmnFlowService bpmnFlowService;

        @Resource
        private PojoDictParseService dictService;

        @Override
        @Transactional(rollbackFor = Exception.class)
        public OaCarApply doSave(OaCarApply oaCarApply) {
            oaCarApply.setOrderStatus(OaEnums.OrderStatus.NEW.getCode());
            oaCarApply.setBpmnStatus(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode());
            this.save(oaCarApply);

            return oaCarApply;
        }

        @Override
        @Transactional
        public OaCarApply submit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaCarApply oaCarApplyOrder = this.getById(OaCarApply.class, request.getBizNo());

            AssertUtil.notNull(oaCarApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            WorkerOrderStatusManager.submitValidate(oaCarApplyOrder.getOrderStatus(), oaCarApplyOrder.getBpmnStatus());

            //1. 开启工作流
            OaCarApply oaCarApply = parseDict(oaCarApplyOrder);
            Map<String, Object> workFlowParam = JacksonMapUtils.convertObjectToMap(oaCarApply);
            ProcessInstance processInstance = bpmnFlowService.startWithFormByKey(request.getKey(), SecurityUtils.getLoginUsername(), request.getBusinessKey(),workFlowParam);
            //2. 更新工单
            oaCarApplyOrder.setOrderStatus(OaEnums.OrderStatus.UNDER_REVIEW.getCode());
            oaCarApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());
            oaCarApplyOrder.setProcessInstanceId(processInstance.getId());
            this.update(oaCarApplyOrder);

            return oaCarApplyOrder;
        }

        @Override
        @Transactional
        public OaCarApply audit(BpmnSubmitRequest request) {

            AssertUtil.notEmpty(request.getBizNo(), BizExceptionEnums.PARAM_NOT_NULL, "bizNo");

            OaCarApply oaCarApplyOrder = this.getById(OaCarApply.class, request.getBizNo());

            AssertUtil.notNull(oaCarApplyOrder, BizExceptionEnums.ORDER_NOT_FOUND);

            List<String> passStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode(),
                OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());

            AssertUtil.notNull(passStatus.contains(request.getBpmnStatus()),BizExceptionEnums.ORDER_AUDIT_STATUS_ERROR);

            //被审批工单允许的状态
            List<String> orderPassStatus = Lists.newArrayList(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode());

            AssertUtil.isTrue(orderPassStatus.contains(oaCarApplyOrder.getBpmnStatus()),BizExceptionEnums.ORDER_UNABLE_AUDIT_BY_STATUS,oaCarApplyOrder.getBpmnStatus());

            if (request.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
                 oaCarApplyOrder.setOrderStatus(OaEnums.OrderStatus.DONE.getCode());
                 oaCarApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
             }else{
                 oaCarApplyOrder.setOrderStatus(OaEnums.OrderStatus.CLOSED.getCode());
                 oaCarApplyOrder.setBpmnStatus(OrderStatusEnums.BpmnStatus.CLOSED.getStatusCode());
             }

             this.update(oaCarApplyOrder);

             return oaCarApplyOrder;
            }

        private OaCarApply parseDict(OaCarApply OaCarApplyOrder) {
            OaCarApply cloneOaCarApply = CloneUtil.deepClone(OaCarApplyOrder, OaCarApply.class);
            Result<OaCarApply> result = Result.OK(cloneOaCarApply);
            dictService.parseDictResult(result);
            return result.getResult();
        }
}